#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <WiFi.h>
#include <WebServer.h>
#include <Adafruit_NeoPixel.h>
#define PIN 18 //灯珠驱动引脚
const char *ssid = "zcgg";
const char *password = "chen88888";
int mode = 3;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_GRB + NEO_KHZ800);
WebServer server(80);

void handleRoot()
{
    // 通常处理根URL（例如：http://192.168.x.x/）
    server.send(200, "text/plain", "Hello from ESP32!");
}

void handleParameters()
{
    // 处理带有参数的URL（例如：http://192.168.x.x/?param1=value1&param2=value2）
    if (server.args() > 0)
    {
        Serial.println("收到请求");
        String message = "Received mode:";
        Serial.println(server.argName(0));
        Serial.println(server.arg(0));
        if (server.argName(0) == "mode")
        {
            Serial.println("mode");
            mode = server.arg(0).toInt();
        }
        server.send(200, "text/plain", message + server.arg(0));
    }
    else
    {
        server.send(200, "text/plain", "No parameters received");
    }
}

void setup()
{
    delay(2000);
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    server.on("/", handleRoot);
    server.on("/params", handleParameters); // 你可以将请求发送到/params来测试参数接收
    server.begin();
    strip.begin();
    strip.setBrightness(50);
    strip.show(); // Initialize all pixels to 'off'
}

void loop()
{
    server.handleClient();
    if (mode == 0)
    {
        Serial.println("mode0");
        /* code */
        colorWipe(strip.Color(255, 0, 0), 50); // Red
        colorWipe(strip.Color(0, 255, 0), 50); // Green
        colorWipe(strip.Color(0, 0, 255), 50); // Blue
    }
    else if (mode == 1)
    {
        Serial.println("mode1");
        theaterChase(strip.Color(127, 127, 127), 20); // White
        theaterChase(strip.Color(127, 0, 0), 20);     // Red
        theaterChase(strip.Color(0, 0, 127), 20);     // Blue
    }
    else if (mode == 2)
    {
        Serial.println("mode2");
        rainbow(20);
    }
    else if (mode == 3)
    {
        Serial.println("mode3");
        rainbowCycle(1);
    }
    else if (mode == 4)
    {
        Serial.println("mode4");
        theaterChaseRainbow(20);
    }
    else
    {
        Serial.println("mode error");
    }
}

// Fill the dots one after the other with a color
// 模式0
void colorWipe(uint32_t c, uint8_t wait)
{
    for (uint16_t i = 0; i < strip.numPixels(); i++)
    {
        server.handleClient();
        if (mode != 0)
        {
            return;
        }
        strip.setPixelColor(i, c);
        strip.show();
        delay(wait);
    }
}

// 彩虹模式 模式2
void rainbow(uint8_t wait)
{
    uint16_t i, j;

    for (j = 0; j < 256; j++)
    {
        server.handleClient();
        if (mode != 2)
        {
            return;
        }
        for (i = 0; i < strip.numPixels(); i++)
        {
            server.handleClient();
            if (mode != 2)
            {
                return;
            }
            strip.setPixelColor(i, Wheel((i + j) & 255));
        }
        strip.show();
        delay(wait);
    }
}

// Slightly different, this makes the rainbow equally distributed throughout
// 模式3
void rainbowCycle(uint8_t wait)
{
    uint16_t i, j;

    for (j = 0; j < 256 * 5; j++)
    { // 5 cycles of all colors on wheel
        server.handleClient();
        if (mode != 3)
        {
            return;
        }

        for (i = 0; i < strip.numPixels(); i++)
        {
            if (mode != 3)
            {
                return;
            }
            server.handleClient();
            strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
        }
        strip.show();
        delay(wait);
    }
}

// Theatre-style crawling lights.
// 模式1
void theaterChase(uint32_t c, uint8_t wait)
{
    for (int j = 0; j < 10; j++)
    { // do 10 cycles of chasing
        server.handleClient();
        if (mode != 1)
        {
            return;
        }
        for (int q = 0; q < 3; q++)
        {
            server.handleClient();
            if (mode != 1)
            {
                return;
            }
            for (uint16_t i = 0; i < strip.numPixels(); i = i + 3)
            {
                server.handleClient();
                if (mode != 1)
                {
                    return;
                }
                strip.setPixelColor(i + q, c); // turn every third pixel on
            }
            strip.show();

            delay(wait);

            for (uint16_t i = 0; i < strip.numPixels(); i = i + 3)
            {
                server.handleClient();
                if (mode != 1)
                {
                    return;
                }
                strip.setPixelColor(i + q, 0); // turn every third pixel off
            }
        }
    }
}

// Theatre-style crawling lights with rainbow effect
// 模式4
void theaterChaseRainbow(uint8_t wait)
{
    for (int j = 0; j < 256; j++)
    { // cycle all 256 colors in the wheel
        server.handleClient();
        if (mode != 4)
        {
            return;
        }
        for (int q = 0; q < 3; q++)
        {
            server.handleClient();
            if (mode != 4)
            {
                return;
            }
            for (uint16_t i = 0; i < strip.numPixels(); i = i + 3)
            {
                server.handleClient();
                if (mode != 4)
                {
                    return;
                }
                strip.setPixelColor(i + q, Wheel((i + j) % 255)); // turn every third pixel on
            }
            strip.show();

            delay(wait);

            for (uint16_t i = 0; i < strip.numPixels(); i = i + 3)
            {
                server.handleClient();
                if (mode != 4)
                {
                    return;
                }
                strip.setPixelColor(i + q, 0); // turn every third pixel off
            }
        }
    }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos)
{
    server.handleClient();
    WheelPos = 255 - WheelPos;
    if (WheelPos < 85)
    {
        return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    if (WheelPos < 170)
    {
        WheelPos -= 85;
        return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    WheelPos -= 170;
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
